/*=============================================================================
*
*   Copyright (C) 2020 All rights reserved.
*
*   Filename:		dof_handler.hpp
*
*   Author: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Date: 2020-02-20 15:39
*
*   Last Editors: Wang Zhecheng - wangzhecheng@yeah.net
*
*   Last modified:	2020-03-30 18:46
*
*   Description:
*
=============================================================================*/
#ifndef DofHANDLER_H
#define DofHANDLER_H

#include "../geometry/mesh/mesh.hpp"
#include "dof.hpp"

namespace geoxfem {
namespace model {

struct DofHandler {
  using DofList = std::vector<Dof*>;

  DofHandler() : m_needChange{true} {}
  DofHandler(const DofHandler&) = default;
  DofHandler(DofHandler&&)      = default;
  ~DofHandler()                 = default;
  DofHandler& operator=(const DofHandler&) = default;
  DofHandler& operator=(DofHandler&&) = default;

  /*direct memeber access{{{*/
  bool ifNeedChange() const {
    return m_needChange;
  }
  void needChange(const bool& value) {
    m_needChange = value;
  }
  void clear() {
    m_listDof.clear();
  }
  size_t getNEQ() const {
    return m_listDof.size();
  }
  void append(Dof* pdof) {
    m_listDof.emplace_back(pdof);
  }
  /*}}}*/
  /*iterator access{{{*/

  DofList::iterator getDofBegin() {
    return m_listDof.begin();
  }
  DofList::iterator getDofEnd() {
    return m_listDof.end();
  }
  DofList::const_iterator getDofBegin() const {
    return m_listDof.begin();
  }
  DofList::const_iterator getDofEnd() const {
    return m_listDof.end();
  }
  /*}}}*/
  template <typename DimensionType, typename degree>
  void update(const geometry::Mesh<DimensionType, degree>& mesh) {
    if(!m_needChange)
      return;
    m_listDof.clear();
    for(auto& vertex : shapesIn(mesh, 0))
      for(auto& dof : dofsIn(vertex->toVertex())) {
        dof.second.setIndex(m_listDof.size());
        append(&dof.second);
      }
    m_needChange = false;
  }

private:
  bool              m_needChange;
  std::vector<Dof*> m_listDof;
};

}  // namespace model
}  // namespace geoxfem

#endif /* DofHANDLER_H */
